﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace BushakwiaRLF
{
    public unsafe static class ProcessClass
    {
        //enum RunLengthStatistic 
        //{
        //    ShortPrimitiveEmphasis,
        //    LongPrimitiveEmphasis,
        //    GrayLevelUniformity,
        //    PrimitiveLengthUniformity,
        //    PrimitivePercentage
        //};

        //enum PrimitiveDirection
        //{
        //    Horizontal,
        //    Vertical,
        //    Both
        //};

        public static Bitmap makeGrayscale(Bitmap source)
        {
            Bitmap newBitmap = new Bitmap(source.Width, source.Height);
            Graphics graphics = Graphics.FromImage(newBitmap);
            ColorMatrix colorMatrix = new ColorMatrix(
                new float[][]
                {
                    new float[] {.3f,.3f,.3f,0,0},
                    new float[] {.59f,.59f,.59f,0,0},
                    new float[] {.11f,.11f,.11f,0,0},
                    new float[] {0,0,0,1,0},
                    new float[] {0,0,0,0,1}
                });
            ImageAttributes attributes = new ImageAttributes();
            attributes.SetColorMatrix(colorMatrix);
            graphics.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height), 0, 0, source.Width, source.Height, GraphicsUnit.Pixel, attributes);
            graphics.Dispose();
            return newBitmap;
        }

        public static int max = Int32.MinValue, min = Int32.MaxValue;



        private static void maxAndMinGrayValue(FastBitmap bitmap)
        {
            for (var x = 0; x < bitmap.width; x++)
                for (var y = 0; y < bitmap.height; y++)
                {
                    int compare = bitmap.GetPixel(x, y).R;
                    max = max > compare ? max : compare;
                    min = min < compare ? min : compare;
                }
        }

        private static Color GetGrayLevel(Color source, int levels)
        {
            double dl = 255.0 / (double)levels;
            double color = (double)source.R;
            int level = 0;
            double currentLevel = dl;
            while (currentLevel < 255)
            {
                if (color <= currentLevel) break;
                currentLevel += dl;
                level++;
            }
            int factor = (int)((double)level * dl);
            return Color.FromArgb(factor, factor, factor);
        }

        public static Bitmap quantize(Bitmap source, int levels)
        {
            //Create a new blank image
            Bitmap newBmp = new Bitmap(source.Width, source.Height);

            //Edit/Read the images with our FastBitmap class
            FastBitmap original = new FastBitmap(source);
            FastBitmap output = new FastBitmap(newBmp);

            //Lock both images to make them editable/readable
            original.LockImage();
            output.LockImage();
            //maxAndMinGrayValue(original);
            //Look through the original image
            for (int x = 0; x < source.Width; x++)
            {
                for (int y = 0; y < source.Height; y++)
                {
                    Application.DoEvents(); //Keep application from crashing

                    Color originalColor = original.GetPixel(x, y);
                    //Match the current bitmap color with the target bitmap
                    output.SetPixel(x, y, GetGrayLevel(originalColor, levels));
                }
            }

            //Unlock the images
            original.UnlockImage();
            output.UnlockImage();

            //Return the final bitmap (not the FastBitmap object)
            return newBmp;
        }

        public static int[] make1DTable(Bitmap bitmap)
        {
            int[] result = new int[bitmap.Width * bitmap.Height];
            for (var j = 0; j < bitmap.Height; j++)
                for (var i = 0; i < bitmap.Width; i++)
                    result[j * bitmap.Width + i] = bitmap.GetPixel(i, j).R;
            return result;

        }

    }
}
